<template>
	<view class="time-range-picker-container" v-if="visibleIn" :style="{'zIndex': zIndex}">
    <view class="time-range-picker-mask" @click="maskClick" :class="{'anipicker': isAniType === 'in', 'anipickerout': isAniType === 'out'}" :style="{'backgroundColor': `rgba(0,0,0,${maskOpacity})`}"></view>
    <view class="picker-main" :class="{'anipicker': isAniType === 'in', 'anipickerout': isAniType === 'out'}">
      <view class="toolbar">
        <text class="toolbar-btn toolbar-cancel" @click="cancel">取消</text>
        <text class="toolbar-title" v-if="title">{{title}}</text>
        <text class="toolbar-btn toolbar-sure" @click="sure">确认</text>
      </view>
      <view class="picker-type" v-if="isShowType">
        <text class="picker-type-item">开始时间</text>
        <text class="picker-type-item">结束时间</text>
      </view>
      <picker-view  
        :indicator-style="indicatorStyle"
        :value="valuIn"
        @change="bindChange"
        class="picker-view"
      >
        <picker-view-column :class="{'point-add': delimiter === 'point'}">
          <view class="item" v-for="(item,index) in hoursStarts" :key="index">{{item}}{{delimiter === 'cn' ? '时' : ''}}</view>
        </picker-view-column>
        <picker-view-column :class="{'point-add': delimiter === 'point' && isShowSecond, 'separate-item': !isShowSecond}">
          <view class="item" v-for="(item,index) in minuteStarts" :key="index">{{item}}{{delimiter === 'cn' ? '分' : ''}}</view>
        </picker-view-column>
        <picker-view-column class="separate-item" v-if="isShowSecond">
          <view class="item" v-for="(item,index) in secondStarts" :key="index">{{item}}{{delimiter === 'cn' ? '秒' : ''}}</view>
        </picker-view-column>
        <picker-view-column :class="{'point-add': delimiter === 'point'}">
          <view class="item" v-for="(item,index) in hoursEnds" :key="index">{{item}}{{delimiter === 'cn' ? '时' : ''}}</view>
        </picker-view-column>
        <picker-view-column :class="{'point-add': delimiter === 'point' && isShowSecond}">
          <view class="item" v-for="(item,index) in minuteEnds" :key="index">{{item}}{{delimiter === 'cn' ? '分' : ''}}</view>
        </picker-view-column>
        <picker-view-column v-if="isShowSecond">
          <view class="item" v-for="(item,index) in secondEnds" :key="index">{{item}}{{delimiter === 'cn' ? '秒' : ''}}</view>
        </picker-view-column>
      </picker-view>
    </view>
</view>
</template>
<script>
	export default {
		props: {
			value: {
				type: [Array, String],
				default() {
					return [];
				}
			},
			// 选择器标题,为空不显示
			title: {
				type: String,
				default: '时间段选择'
			},
			// 控制picker显示/隐藏
			visible:{
				type: Boolean,
				default: false
			},
			// 是否展示时间标签
			isShowType: {
				type: Boolean,
				default: true
			},
			// 分隔符类型
			delimiter: {
				type: String,
				validator: (value) => {
					return ['cn', 'point', 'none'].indexOf(value) !== -1;
				},
				default: 'cn'
			},
			// 是否到秒
			isShowSecond: {
				type: Boolean,
				default: true
			},
			// 时间选择器层级
			zIndex: {
				type: Number,
				default: 9999
			},
			limitStart: {
				type: [String,Array],
				default() {
					return ['00','00','00'];
				}
			},
			limitEnd: {
				type: [String,Array],
				default() {
					return ['23','59','59'];
				}
			},
      // 是否显示遮罩
      maskOpacity: {
        type: [String,Number],
        default: 0.75
      },
      // 是否有动效
      isAni: {
        type: Boolean,
        default: false
      },
      // 是否允许遮罩点击关闭
      isMaskClose: {
      	type: Boolean,
      	default: false
      },
		},
		data() {
			return {
        visibleIn: false,
        isAniType: false,
				valuIn: [],
				hoursStarts: [],
				minuteStarts: [],
				secondStarts: [],
				hoursStartIndex: 0,
				minuteStartIndex: 0,
				secondStartIndex: 0,
				hoursEndIndex: 0,
				minuteEndIndex: 0,
				secondEndIndex: 0,
				indicatorStyle: `height: 50px;`
			}
		},
		mounted() {
			this.result = [];
			this.init();
		},
		watch:{
			visible(newVal, oldVal) {
				this.showHide(newVal);
			},
			value(newVal, oldVal) {
				if (newVal) {
					this.init();
				}
			},
      hoursEnds(newVal, oldVal) {
        const oldv = oldVal[this.hoursEndIndex];
        const index = newVal.findIndex((item) => item === oldv);
        if (!oldv) return;
        this.hoursEndIndex = index !== -1 ? index : 0;
        console.log('---- this.hoursEndIndex ----:',  this.hoursEndIndex, index);
        this.setResult(this.hoursStartIndex, this.minuteStartIndex, this.isShowSecond ? this.secondStartIndex : -1, this.hoursEndIndex, this.minuteEndIndex, this.isShowSecond ? this.secondEndIndex : -1);
      },
      minuteEnds(newVal, oldVal) {
        const oldv = oldVal[this.minuteEndIndex];
        const index = newVal.findIndex((item) => item === oldv);
        if (!oldv) return;
        this.minuteEndIndex = index !== -1 ? index : 0;
        this.setResult(this.hoursStartIndex, this.minuteStartIndex, this.isShowSecond ? this.secondStartIndex : -1, this.hoursEndIndex, this.minuteEndIndex, this.isShowSecond ? this.secondEndIndex : -1);
      },
      secondEnds(newVal, oldVal) {
        const oldv = oldVal[this.secondEndIndex];
        if (!oldv) return;
        const index = newVal.findIndex((item) => item === oldv);
        this.secondEndIndex = index !== -1 ? index : 0;
        this.setResult(this.hoursStartIndex, this.minuteStartIndex, this.isShowSecond ? this.secondStartIndex : -1, this.hoursEndIndex, this.minuteEndIndex, this.isShowSecond ? this.secondEndIndex : -1);
      }
		},
		computed: {
			hoursEnds() {
				const hours = [];
				const hoursStartValue = parseInt(this.hoursStarts[this.hoursStartIndex]);
				for (let i=hoursStartValue; i<=parseInt(this.limitEnds[0]); i++) {
					hours.push((i + '').padStart(2, '0'));
				}
				// this.hoursEndIndex = 0;
				return hours;
			},
			minuteEnds() {
				const minutes = [];
				let startIndex = parseInt(this.limitStarts[1]);
				if (this.hoursEndIndex === 0) {
					startIndex = parseInt(this.minuteStarts[this.minuteStartIndex]);
				}
				for (let i=startIndex; i<=parseInt(this.limitEnds[1]); i++) {
					minutes.push((i + '').padStart( 2, '0')); 
				}
				return minutes;
			},
			secondEnds() {
				if (!this.isShowSecond) {
					return [];
				}
				const seconds = [];
				let startIndex = parseInt(this.limitStarts[2]);
				if (this.hoursEndIndex === 0 && this.minuteEndIndex === 0) {
					startIndex = parseInt(this.secondStarts[this.secondStartIndex]);
				}
				for (let i=startIndex; i<=parseInt(this.limitEnds[2]); i++) {
					seconds.push((i + '').padStart(2, '0'));
				}
				return seconds;
			},
			limitStarts() {
				if (typeof this.limitStart === 'string') {
					if (this.limitStart === 'now') {
						const date = new Date();
						return [date.getHours(), date.getMinutes(), date.getSeconds()];
					}
					return this.limitStart.split(/[年月日:]/).filter((item) => item !== '')
				}
				return this.limitStart;
			},
			limitEnds() {
				if (typeof this.limitEnd === 'string') {
					return this.limitEnd.split(/[年月日:]/).filter((item) => item !== '')
				}
				return this.limitEnd;
			}
		},
		methods: {
			init() {
				const hours = [];
				for (let i = parseInt(this.limitStarts[0]); i<=parseInt(this.limitEnds[0]); i++) {
					hours.push((i + '').padStart(2, '0'));
				}
				const minutes = [];
				const seconds = [];
				for (let i=parseInt(this.limitStarts[1]); i<=parseInt(this.limitEnds[1]); i++) {
					minutes.push((i + '').padStart(2, '0'));
				}
				if (this.limitStarts[2]) {
					for (let i=parseInt(this.limitStarts[2]); i<=parseInt(this.limitEnds[2]); i++) {
						seconds.push((i + '').padStart(2, '0'));
					}
				}
				this.hoursStarts = hours;
				this.minuteStarts = minutes;
				this.secondStarts = this.isShowSecond ? seconds : [];
				if (this.value) {
          let values = [];
          if (Array.isArray(this.value)) {
            values = this.value;
          } else if(typeof this.value === 'string') {
            values = this.value.split(/[时分秒\-:]/).filter((item) => item !== '');
          }
          this.hoursStartIndex = this.hoursStarts.findIndex((item) => item === values[0]);
          this.minuteStartIndex = this.minuteStarts.findIndex((item) => item === values[1]);
          this.secondStartIndex = this.isShowSecond ? this.secondStarts.findIndex((item) => item === values[2]) : -1;
					setTimeout(() => {
						this.hoursEndIndex = this.hoursEnds.findIndex((item) => item === (this.isShowSecond ? values[3] : values[2]));
						this.minuteEndIndex = this.minuteEnds.findIndex((item) => item === (this.isShowSecond ? values[4] : values[3]));
						this.secondEndIndex = this.isShowSecond ? this.secondEnds.findIndex((item) => item === values[5]) : -1;
						this.setResult(this.hoursStartIndex, this.minuteStartIndex, this.secondStartIndex, this.hoursEndIndex, this.minuteEndIndex, this.secondEndIndex);
					}, 100);
					return;
				}
				this.setResult(0,0,this.isShowSecond ? 0 : -1,0,0,this.isShowSecond ? 0 : -1);
			},
			cancel() {
        this.showHide(false);
				this.$emit('cancel');
			},
			sure() {
				this.$emit('sure', this.result);
			},
			setResult(hoursStartIndex, minuteStartIndex,secondStartIndex, hoursEndIndex, minuteEndIndex, secondEndIndex) {
				this.hoursStartIndex = hoursStartIndex;
				this.minuteStartIndex = minuteStartIndex;
				this.secondStartIndex = secondStartIndex;
				this.hoursEndIndex = hoursEndIndex;
				this.minuteEndIndex = minuteEndIndex;
				this.secondEndIndex = secondEndIndex;
        const hoursStartVal = this.hoursStarts[this.hoursStartIndex];
        const minuteStartVal = this.minuteStarts[this.minuteStartIndex];
        const secondStartVal = this.secondStarts[this.secondStartIndex];
        setTimeout(() => {
          const hoursEndVal = this.hoursEnds[this.hoursEndIndex];
          const minuteEndVal = this.minuteEnds[this.minuteEndIndex];
          const secondEndVal = this.secondEnds[this.secondEndIndex];
          this.valuIn = this.isShowSecond ? [hoursStartIndex, minuteStartIndex,secondStartIndex, hoursEndIndex, minuteEndIndex, secondEndIndex] : [hoursStartIndex, minuteStartIndex, hoursEndIndex, minuteEndIndex];
          this.result = {
            index: [hoursStartIndex, minuteStartIndex,secondStartIndex, hoursEndIndex, minuteEndIndex, secondEndIndex].filter((item) => item > -1),
            values: [hoursStartVal, minuteStartVal, secondStartVal, hoursEndVal, minuteEndVal, secondEndVal].filter((item) => item),
            valuesStr0: `${hoursStartVal}时${minuteStartVal}分${this.isShowSecond ? secondStartVal + '秒' : ''}-${hoursEndVal}时${minuteEndVal}分${this.isShowSecond ? secondEndVal + '秒' : ''}`,
            valuesStr1: `${hoursStartVal}:${minuteStartVal}${this.isShowSecond ? ':'+secondStartVal : ''}-${hoursEndVal}:${minuteEndVal}${this.isShowSecond ? ':'+secondEndVal : ''}`,
          }
        }, 100);
			},
			bindChange(e) {
				console.log('---- bindChange ----:', e)
				// this.valuIn = e.detail.value;
        if (this.isShowSecond) {
          const [hoursStartIndex, minuteStartIndex,secondStartIndex, hoursEndIndex, minuteEndIndex, secondEndIndex] = e.detail.value;
          this.setResult(hoursStartIndex, minuteStartIndex,secondStartIndex, hoursEndIndex, minuteEndIndex, secondEndIndex);
        } else {
          const [hoursStartIndex, minuteStartIndex, hoursEndIndex, minuteEndIndex] = e.detail.value;
          this.setResult(hoursStartIndex, minuteStartIndex,-1, hoursEndIndex, minuteEndIndex, -1);
        }
        setTimeout(() => {
          this.$emit('change', this.result);
        }, 200);
			},
      // 显示隐藏逻辑
      showHide(newVal) {
        if (newVal) {
        	this.init();
          this.visibleIn = newVal;
          if (this.ani) {
            this.isAniType = 'in';
          }
        } else {
          if (this.isAni) {
            this.isAniType = 'out';
            setTimeout(() => {
              this.visibleIn = newVal;
              this.isAniType = '';
            }, 200);
          } else {
            this.visibleIn = newVal;
          }
        }
      },
      // 弹窗显示
      show() {
        this.showHide(true);
        this.$emit('update:visible', true);
      },
      // 弹窗关闭
      hide() {
        this.showHide(false);
				this.$emit('update:visible', false);
      },
      maskClick() {
        if (this.isMaskClose) {
          this.hide();
        }
      }
		}
	}
</script>
<style lang="scss" scoped>
  @keyframes ani{
  	0%{
  		opacity: 0;
  	}
  	100%{
  		opacity: 1;
  	}
  }
	.time-range-picker-container{
		position: fixed;
		bottom: 0;
		left: 0;
    top: 0;
    right: 0;
	}
  .time-range-picker-mask{
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    &.anipicker{
      animation: ani .1s linear 0s 1 forwards;
    }
    &.anipickerout{
      animation: ani .1s linear 0.1s 1 reverse;
    }
  }
  @keyframes cutIn{
  	0%{
  		transform: translateY(50%);
      opacity: 0;
  	}
  	100%{
  		transform: translateY(0);
  		opacity: 1;
  	}
  }
  .picker-main{
    position: absolute;
    bottom: 0;
    left: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    border-radius: 24rpx 24rpx 0 0;
    overflow: hidden;
    border-top: 1px solid #E8E8E8;
    box-shadow: 0 0 15rpx rgba(0,0,0,.1);
    background-color: #fff;
    &.anipicker{
      animation: cutIn .2s linear 0s 1 forwards;
    }
    &.anipickerout{
      animation: cutIn .2s linear 0s 1 reverse;
    }
  }
	.toolbar{
		display: flex;
		justify-content: space-between;
		align-items: center;
		.toolbar-btn{
			padding:36rpx 32rpx;
			line-height: 44rpx;
			font-size: 32rpx;
		}
		.toolbar-cancel{
			color: rgba(0, 0, 0, 0.6);
		}
		.toolbar-sure{
			color: rgba(40, 126, 255, 1);
		}
		.toolbar-title{
			flex:1;
			overflow: hidden;
			white-space: nowrap;
			text-overflow: ellipsis;
			font-size: 36rpx;
			text-align: center;
			font-weight: 700;
			color: rgba(0, 0, 0, 0.9);
		}
	}
	.picker-view {
		width: 750rpx;
		padding:0 32rpx;
		box-sizing: border-box;
		height: 400rpx;
	}
	.item {
		line-height: 80rpx;
		font-size: 32rpx;
		text-align: center;
		color: rgba(0, 0, 0, 0.9);
	}
	.separate-item{
		position: relative;
		overflow: visible;
		margin-right: 68rpx;
		&::after{
			content: ' ';
			width: 68rpx;
			height: 2rpx;
			position: absolute;
			top: 50%;
			transform: translateY(-1rpx);
			right: -68rpx;
			background-image: linear-gradient(to right, transparent, #ccc, transparent);
		}
	}
	.point-add{
		position: relative;
		overflow: visible;
		&::after{
			content: ':';
			width: 32rpx;
			text-align: center;
			line-height: 1.5;
			font-size: 24rpx;
			position: absolute;
			top: 50%;
			transform: translateY(-28rpx);
			right: -16rpx;
		}
	}
	.picker-type{
		width: 100%;
		display: flex;
		.picker-type-item{
			flex:1;
			text-align: center;
			font-size: 32rpx;
			line-height: 1.5;
			color: #ccc;
		}
	}
</style>
